package com.kou.backend.util;

import cn.hutool.jwt.JWT;
import com.kou.backend.property.JwtProperties;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * jwt token工具类
 * 基于hutool工具包
 *
 * @author: Chaojie.Kou
 * @since: 2023/8/30 10:49
 */
@Component
public class JwtTokenUtils {
    private static final String USER_ACCOUNT = "userAccount";

    @Resource
    private RedisUtil redisUtil;
    @Resource
    private JwtProperties jwtProperties;

    /**
     * 生成JWT令牌
     *
     * @param userAccount 用户名
     * @param userName    用户名称
     * @return JWT令牌
     */
    public String generateToken(String userAccount, String userName) {
        return JWT.create()
                .setPayload(USER_ACCOUNT, userAccount)
                .setPayload("userName", userName)
                .setKey(jwtProperties.getJwtSecret().getBytes())
                .sign();
    }

    /**
     * 根据token获取其中的负载
     *
     * @param token token
     * @return map载荷信息
     */
    public Map<String, Object> getClaimsFromToken(String token) {
        return JWT.of(token).getPayloads();
    }

    /**
     * 校验JWT令牌是否有效
     *
     * @param token JWT令牌
     * @return Claims对象，包含JWT令牌中的信息
     */
    public boolean verify(String token) {
        boolean verify = JWT.of(token).setKey(jwtProperties.getJwtSecret().getBytes()).verify();
        //如果jwt token有效并且redis中存在这个用户的key则有效
        return verify && redisUtil.hasKey(jwtProperties.getKeyPrefix() + getClaimsFromToken(token).get(USER_ACCOUNT));
    }

    /**
     * 刷新JWT令牌
     *
     * @param token JWT令牌
     */
    public void refreshToken(String token) {
        //key为前缀+用户帐号,value为对应token
        redisUtil.setExpireTime(jwtProperties.getKeyPrefix() + getClaimsFromToken(token).get(USER_ACCOUNT), jwtProperties.getExpiration());
    }

    /**
     * 删除token
     *
     * @param token token
     */
    public void clearToken(String token) {
        List<String> keys = new ArrayList<>();
        keys.add(jwtProperties.getKeyPrefix() + getClaimsFromToken(token).get(USER_ACCOUNT));
        redisUtil.delete(keys);
    }
}
